Subroutines in Perl

Defining Subroutines

o Use the keyword sub

o Subroutines can have ampersand (&) in the front of the name or not

o By default, all subroutines are global (public); requires advanced methods to make them private

o Two of the exact same subroutine names can be defined, but the first one is overrided by the later one

o Variables are also global by default, both within and outside of the subroutine

o Subroutine names cannot start with a number

sub marine {
 print “hello world”;
 }
  • Invoking Subroutines

o Subroutine name preceded by ampersand (&)

&marine;
  • Subroutine Return Values

o All Perl subroutines have a useful return value, whether declared to return something or not

o If not declared, by default, the subroutine returns the last calculation it performed

o Caution: If the last calculation in a subroutine was a print statement, then it would return 1

$x = &myfunc1;
 print $x; # prints 101
 $x = &myfunc2;
 print $x; # prints 1

sub myfunc1 {
 $somevar = 100 + 1;
 }

sub myfunc2 {
 $somevar = 100 + 1; # Calculation
 print "hello world"; # Last calculation is print statement
 }
  • Arguments

o Use parentheses to pass subroutine arguments

o Passed arguments are held in the @_ variable (default array of arguments) within the subroutine

o These values are accessed as follows in the subroutine:

$_[0];
 $_[1];
  • And like regular arrays, undefined indexes have the scalar undef value and extra arguments are simply ignored (truncated)
  • Private Variables

o Private variables, or lexical variables have only the scope of the subroutine

o These variables are defined using the keyword my

o Example:

sub max {

if(@_ != 2) { print 'warning'; } #checking for at least 2 arguments

my($a, $b);

($a, $b) = @_;
 }
  • Example of handling dynamic amount of arguments and finding the max number
sub max {

my($currentmax) = shift @_; # takes the first element from input array

foreach (@_) {

if($_ > $currentmax) { $currentmax = $_; }

}

$currentmax; # last calculation, therefore the return value

}
  • Note that in the above example, if an empty array is passed, the subroutine would pass a undef value. This is because when setting currentmax variable, it pulls an undef from the empty array.
  • Private variables can be limited to the scope of a subroutine, or a condition or loop as well. Any variable defined with my() within brackets is limited scope to within those brackets only. All private variables must be defined within the parentheses.
foreach (1..10) { # variables below are limited to scope of this loop only

my $var1, $var2; # WRONG!, $var2 will not be declared
 my ($var1, $var2); # correct!

}
  • strict Pragma

o Pragma is a hint to the compiler to follow some rule for this section of code

o At top of file, include

  • use strict;
  • Enforces all variables to be defined before they can be used
  • Removes usage of global variables
  • Omitting the Ampersand

o Two cases in which ampersands are required

  • If the function definition comes after the function call, should use ampersand
  • If the function name is same a Perl built in function, must use ampersand

o Generally good practice to make all subroutine calls using ampersand

  • return Operator

o Can be used in subroutine to immediately return a value / ends subroutine

o May be good practice to always include a return statement, though not necessary

  • state variables – Persistent Private Variable

o Any scalar or list variable can be defined as state

o State variables are scoped to the subroutine but Perl will keep their values in between calls

o Example

sum (1,2);
 sum (3..5);
 sum (6, 7);

sub sum {
 state $sum = 0;
 state @numbers;

foreach my $number (@_) {
 push @numbers, $number;
 $sum += $number;
 }
 }
 # After the sum function is called all 3 times, the @numbers array will contain 1,2,3,4,5,6,7 and the sum will be 7! (factorial).